﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RedBlueBalls
{
    class RedEdge
    {
        private static bool analyzed = false;
        private static bool checkBest = false;
        private const int RED_BALL = 6;
        private const int SUM_DEP = 10; // 1/11
        private const int DELTA_DEP = 5; // 1/6
        private const int MEAN_DEP = 5; // 1/6
        private static bool hasSum;
        private static bool hasDelta;
        private static bool hasMean; 
        private static int lastSum;
        private static int lastDelta;
        private static int lastMean; 

        public static void analyze(RedBlueBallRecord[] records)
        {
            if (checkBest)
            {
                int sumCount = 0;
                int deltaCount = 0;
                int meanCount = 0;
                for (int i = records.Length - 1; i > 1; i--)
                {
                    int[] reds = records[i-1].GetReds();
                    int edgeSum = GetEdgeSum(reds);
                    int edgeDelta = GetEdgeDelta(reds);
                    int edgeMean = GetEdgeMean(reds);
                    if (records[i].HasRedBall(edgeSum))
                        sumCount++;
                    if (records[i].HasRedBall(edgeDelta))
                        deltaCount++;
                    if (records[i].HasRedBall(edgeMean))
                        meanCount++;
                }

                Tracer.AppendMessage(String.Format("Edge Sum {0} / Total {1}", sumCount, records.Length));
                Tracer.AppendMessage(String.Format("Edge Delta {0} / Total {1}", deltaCount, records.Length));
                Tracer.AppendMessage(String.Format("Edge Mean {0} / Total {1}", meanCount, records.Length));

            }

            hasSum = false;
            hasDelta = false;
            hasMean = false;
            for (int i = 0; i < SUM_DEP; i++)
            {
                if (records[records.Length - 1 - i].HasRedBall(GetEdgeSum(records[records.Length - 2 - i].GetReds())))
                    hasSum = true; ;
            }
            for (int i = 0; i < DELTA_DEP; i++)
            {
                if (records[records.Length - 1 - i].HasRedBall(GetEdgeDelta(records[records.Length - 2 - i].GetReds())))
                    hasDelta = true; ;
            }
            for (int i = 0; i < MEAN_DEP; i++)
            {
                if (records[records.Length - 1 - i].HasRedBall(GetEdgeMean(records[records.Length - 2 - i].GetReds())))
                    hasMean = true; ;
            }

            int[] lastReds = records[records.Length - 1].GetReds();
            lastSum = GetEdgeSum(lastReds);
            lastDelta = GetEdgeDelta(lastReds);
            lastMean = GetEdgeMean(lastReds);

            analyzed = true;
        }

        public static bool predict(RedBlueBallRecord candidate)
        {
            if (!analyzed)
            {
                Tracer.AppendMessage("Please analyze the data first!");
                return false;
            }

            if (hasSum)
            {
                if (candidate.HasRedBall(lastSum))
                    return false;
            }
            else if (!candidate.HasRedBall(lastSum))
                return false;

            if (hasDelta)
            {
                if (candidate.HasRedBall(lastDelta))
                    return false;
            }
            else if (!candidate.HasRedBall(lastDelta))
                return false;

            if (hasMean)
            {
                if (candidate.HasRedBall(lastMean))
                    return false;
            }
            else if (!candidate.HasRedBall(lastMean))
                return false;

            return true;
        }

        private static int GetEdgeSum(int[] reds)
        {
            return reds[0] + reds[RED_BALL - 1];
        }

        private static int GetEdgeDelta(int[] reds)
        {
            return reds[RED_BALL - 1] - reds[0];
        }

        private static int GetEdgeMean(int[] reds)
        {
            return (reds[0] + reds[RED_BALL - 1])/2;
        }
    }
}
